package service

import (
	"context"
	"fmt"
	"go-file-perception-model/internal/config"
	"go-file-perception-model/internal/model"
	"go-file-perception-model/internal/repository"
	"go-file-perception-model/pkg/vector"
	"os"
	"path/filepath"
)

// EmbeddingModel 嵌入模型接口
type EmbeddingModel interface {
	Embedding(ctx context.Context, text string) ([]float32, error)
	BatchEmbedding(ctx context.Context, texts []string) ([][]float32, error)
	Close() error
	GetModelInfo() map[string]interface{}
}

// FileService 文件服务 - 重构后的协调器
type FileService struct {
	fileRepo      repository.FileRepository
	vectorDB      vector.VectorDB
	indexManager  *IndexManager
	searchService *SearchService
	systemService *SystemService
	fileMonitor   *FileMonitor
	config        *config.FileIndexConfig
}

// NewFileService 创建文件服务实例
func NewFileService(fileRepo repository.FileRepository, embeddingModel EmbeddingModel, cfg *config.FileIndexConfig, fullConfig *config.Config) *FileService {
	vectorDB := fileRepo.GetVectorDB()

	// 创建文件监控仓库
	var fileMonitorRepo repository.FileMonitorRepository

	// 确保数据目录存在
	if err := os.MkdirAll("./data", 0755); err != nil {
		panic("无法创建数据目录: " + err.Error())
	}

	// 获取当前工作目录的绝对路径
	cwd, err := os.Getwd()
	if err != nil {
		panic("无法获取当前工作目录: " + err.Error())
	}

	// 使用绝对路径创建SQLite数据库文件
	dbPath := filepath.Join(cwd, "data", "file_monitor.db")
	fileMonitorRepo, err = repository.NewFileMonitorRepository(dbPath)
	if err != nil {
		panic("无法创建SQLite数据库: " + err.Error())
	}

	// 创建各个子服务
	fileCollector := NewFileCollector(cfg)
	fileProcessor := NewFileProcessor(embeddingModel, cfg)
	directoryMgr := NewDirectoryManager(fileMonitorRepo, vectorDB)
	indexManager := NewIndexManager(fileRepo, fileProcessor, fileCollector, directoryMgr, fileMonitorRepo, cfg)
	searchService := NewSearchService(vectorDB, embeddingModel, fileCollector, fileMonitorRepo)
	systemService := NewSystemService(vectorDB, indexManager, fileProcessor, fileCollector, fullConfig)
	fileMonitor := NewFileMonitor(indexManager, directoryMgr, fileMonitorRepo, cfg)

	return &FileService{
		fileRepo:      fileRepo,
		vectorDB:      vectorDB,
		indexManager:  indexManager,
		searchService: searchService,
		systemService: systemService,
		fileMonitor:   fileMonitor,
		config:        cfg,
	}
}

// 索引管理相关方法 - 委托给IndexManager
func (s *FileService) StartIndexing(req model.IndexRequest) (string, error) {
	return s.indexManager.StartIndexing(req)
}

func (s *FileService) GetIndexStatus() (*model.IndexStatus, error) {
	return s.indexManager.GetIndexStatus()
}

func (s *FileService) ClearIndexChunks(directory string) error {
	return s.indexManager.ClearIndexChunks(directory)
}

// 搜索相关方法 - 委托给SearchService
func (s *FileService) SemanticSearch(req model.SemanticSearchRequest) ([]*model.SearchResult, error) {
	// 如果向量数据库或嵌入模型不可用，则无法进行语义搜索
	if s.vectorDB == nil {
		return nil, fmt.Errorf("vector database is not available")
	}
	return s.searchService.SemanticSearch(req)
}

func (s *FileService) RegexSearch(req model.RegexSearchRequest) ([]*model.SearchResult, error) {
	return s.searchService.RegexSearch(req)
}

// 系统相关方法 - 委托给SystemService
func (s *FileService) GetSystemStats() (*model.SystemStats, error) {
	return s.systemService.GetSystemStats()
}

func (s *FileService) GetFileList(directory string, recursive bool) ([]*model.FileInfo, error) {
	return s.systemService.GetFileList(directory, recursive)
}

func (s *FileService) GetFileContent(filePath string) (string, error) {
	return s.systemService.GetFileContent(filePath)
}

func (s *FileService) ResolveFilePath(filePath string) (string, error) {
	return s.systemService.ResolveFilePath(filePath)
}

func (s *FileService) GetPointByID(ctx context.Context, pointID string) (*model.SearchResult, error) {
	// 如果向量数据库不可用，则无法获取点信息
	if s.vectorDB == nil {
		return nil, fmt.Errorf("vector database is not available")
	}
	return s.systemService.GetPointByID(ctx, pointID)
}

// 文件监控相关方法 - 委托给FileMonitor
func (s *FileService) StartFileMonitoring() error {
	return s.fileMonitor.StartFileMonitoring()
}

func (s *FileService) StopFileMonitoring() error {
	return s.fileMonitor.StopFileMonitoring()
}

func (s *FileService) IsFileMonitoringRunning() bool {
	return s.fileMonitor.IsRunning()
}

// 目录管理相关方法 - 简化实现
func (s *FileService) GetIndexDirectories() ([]string, error) {
	return s.config.IndexDirectories, nil
}

func (s *FileService) AddIndexDirectory(directory string) error {
	// 简化实现：添加到配置中
	for _, dir := range s.config.IndexDirectories {
		if dir == directory {
			return nil // 已存在
		}
	}
	s.config.IndexDirectories = append(s.config.IndexDirectories, directory)
	return nil
}

func (s *FileService) RemoveIndexDirectory(directory string) error {
	// 简化实现：从配置中移除
	for i, dir := range s.config.IndexDirectories {
		if dir == directory {
			s.config.IndexDirectories = append(s.config.IndexDirectories[:i], s.config.IndexDirectories[i+1:]...)
			return nil
		}
	}
	return nil
}

func (s *FileService) UpdateIndexDirectoryStatus(directory string, enabled bool) error {
	// 简化实现：暂时不支持单独的启用/禁用状态
	return nil
}

// SetIndexDirectories 设置索引目录列表
func (s *FileService) SetIndexDirectories(directories []string) error {
	// 验证目录列表
	if len(directories) == 0 {
		return nil // 或者返回错误，取决于需求
	}

	// 去重
	uniqueDirs := make([]string, 0)
	dirMap := make(map[string]bool)
	for _, dir := range directories {
		if dir != "" && !dirMap[dir] {
			dirMap[dir] = true
			uniqueDirs = append(uniqueDirs, dir)
		}
	}

	// 更新配置
	s.config.IndexDirectories = uniqueDirs

	// 保存配置到文件
	if err := s.config.Save(); err != nil {
		return err
	}

	return nil
}

// GetIndexManager 获取索引管理器
func (s *FileService) GetIndexManager() *IndexManager {
	return s.indexManager
}
